<?php

class Curl {

    private $curl;
    private $global_timeout = 3000;
    private $conn_timeout = 1000;
    private $keep_alive_timeout = 300;
    private $header = [];
    private $cookies = [];
    private $user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36';
    private $need_cert = FALSE;
    private $ssl_port = 443;
    public $ssl_cert_path = '';
    public $ssl_cert_passwd = '';
    public $ssl_cert_type = 'pem';

    public function __construct() {
        $this->curl = curl_init();
        curl_setopt_array($this->curl, array(
            //返回文本
            CURLOPT_RETURNTRANSFER => TRUE,
            //允许重定向
            CURLOPT_FOLLOWLOCATION => TRUE,
            //最大重定向次数
            CURLOPT_MAXREDIRS => 10,
            //设置毫秒超时必须启用
            CURLOPT_NOSIGNAL => 1,
            //连接超时
            CURLOPT_CONNECTTIMEOUT_MS => $this->conn_timeout,
            //curl执行超时
            CURLOPT_TIMEOUT_MS => $this->global_timeout,
            //验证对方证书
            CURLOPT_SSL_VERIFYPEER => FALSE,
            //验证对方证书的host
            CURLOPT_SSL_VERIFYHOST => FALSE,
            //不支持session cookie
            CURLOPT_COOKIESESSION => TRUE,
            //ua
            CURLOPT_USERAGENT => $this->user_agent
        ));
    }

    public function setOpt($key, $val) {
        curl_setopt($this->curl, $key, $val);
    }

    public function addHeader($header) {
        $this->header[] = $header;
    }

    public function setCookies(array $cookies) {
        $this->cookies = $cookies;
    }

    public function getCookies() {
        return $this->cookies;
    }

    public function setUserAgent($user_agent) {
        $this->user_agent = $user_agent;
    }

    public function combineCookies() {
        if (!$this->cookies) {
            return;
        }
        $cookies = [];
        foreach ($this->cookies as $_k => $_v) {
            $cookies[] = sprintf('%s=%s', $_k, $_v);
        }
        curl_setopt($this->curl, CURLOPT_COOKIE, implode(';', $cookies));
    }

    public function __destruct() {
        $this->close();
    }

    public function close() {
        is_resource($this->curl) && curl_close($this->curl);
    }

    public function httpGet($url, &$response, $charset = NULL) {
        return $this->_exec($url, $response, $charset);
    }

    public function httpPost($url, &$response, $postData = NULL, $charset = NULL) {
        $postData && curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postData);
        return $this->_exec($url, $response, $charset);
    }

    private function _exec($url, &$response, $charset) {
        curl_setopt($this->curl, CURLOPT_URL, $url);
        curl_setopt($this->curl, CURLOPT_USERAGENT, $this->user_agent);
        if ($this->keep_alive_timeout > 0) {
            $this->header[] = 'Keep-Alive: ' . $this->keep_alive_timeout;
            $this->header[] = 'Connection: keep-alive';
        } else {
            $this->header[] = 'Connection: close';
        }

        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->header);
        $this->getCertificate();
        $this->combineCookies();

        $response = curl_exec($this->curl);
        if ($response === FALSE) {
            return $this->getErrMsg();
        }
        if ($charset) {
            $response = iconv($charset, 'UTF-8//IGNORE', $response);
        }
        return FALSE;
    }

    public function getErrMsg() {
        return sprintf('errorno=%d,errmsg=%s', curl_errno($this->curl), curl_error($this->curl));
    }

    private function getCertificate() {
        if (!$this->need_cert) {
            return;
        }

        $this->ssl_port > 0 && curl_setopt($this->curl, CURLOPT_PORT, $this->ssl_port);
        curl_setopt($this->curl, CURLOPT_SSLCERT, $this->ssl_cert_path);
        curl_setopt($this->curl, CURLOPT_SSLCERTPASSWD, $this->ssl_cert_passwd);
        curl_setopt($this->curl, CURLOPT_SSLCERTTYPE, $this->ssl_cert_type);
    }
}
